;TIP1344.LSP:    SP.LSP    3D Spiral stairs    (c)1997, Xu-Hong Yang 

(defun dtr (r)
  (* r (/ pi 180.0)))
(defun rtd (r)
  (* r (/ 180.0 pi)))

(defun spinfo ()                                        ; staircase parameter
  (setq cp    (getpoint "\nCenter of Spiral Staircase: ")
        lp    (getpoint cp "\nLocation of first tread at inner radius: ")
        riser (getdist lp "\nRiser height: ")
        step  (getdist lp "\nMinimum tread depth at inner radius: ")
        wide  (getdist lp "\nStair width: ")
        hrl   (getdist lp "\nHeight of Handrail: ")
        thi   (getdist lp "\nThickness of Slab: ")
        case  (getint "\nNo. of treads: ")
        ls (sqrt (+ (expt riser 2) (expt step 2)))
        a (/ riser ls)    ; sin A
        b (/ step ls)     ; cos A
        c lp
  )        
)           ; end SPINFO

(defun spcalc ()
  (initget "L R B N") 
  (setq ans (getkword "\n(L)eft/(R)ight/(B)oth-side/(N)one for Handrail: "))
  (setq blksp (open "blksp.lst" "r"))
  (if (not (equal blksp nil))
      (setq blk (read-line blksp))
  )
  (if (equal blk nil)
      (setq blk "sp1")
      (setq blk (strcat "sp"
                        (itoa (1+ (atoi (substr blk 3)))))
      )
  )
  (setq r (distance cp lp))
  (setq ang (/ step r))         ; determines the angle of the step
  (setq ac (angle cp lp))
  (setq rp (polar lp ac wide)
        lp1 (list (car lp) (cadr lp) riser)
        lp4 (list (car rp) (cadr rp) riser)
        count 0
        el riser
        al ang
  )         
  (setq diag (+ ac ang))
  (setq lp2 (list (car (polar cp diag r)) 
                  (cadr (polar cp diag r)) 
                   riser)
        lp3 (list (car (polar cp diag (+ r wide)))
                  (cadr (polar cp diag (+ r wide)))
                   riser)
        lh (polar cp (+ ac (/ ang 2)) (+ r (/ wide 15)))       ; left bottom hrl 
        lh1 (list (car lh) (cadr lh) (+ (caddr lh) riser))      
        lh2 (list (car lh1) (cadr lh1) (+ (caddr lh1) hrl))    ; left top hrl
        sht (polar cp diag (+ r (/ wide 15)))
        shb (polar cp ac (+ r (/ wide 15)))
        sh1 (list (car shb) (cadr shb) (+ (caddr shb) (+ hrl (/ riser 2))))
        sh2 (list (car sht) (cadr sht) (+ (caddr sht) hrl (* riser 1.5)))
  )
  (setq tlp (list (car lp) (cadr lp) (- (caddr lp) (/ thi b)))
        tl1 (list (car lp2) (cadr lp2) (- (caddr lp2) (/ thi b)))
        trp (list (car rp) (cadr rp) (- (caddr rp) (/ thi b))) 
        tr1 (list (car lp3) (cadr lp3) (- (caddr lp3) (/ thi b))))
  (command "layer" "m" "spiral" ""                 ; set spiral layer and color
           "layer" "c" "blue" "" "")
  (command "3dface" lp1 "i" lp2 lp3 lp4 ""         ; draw the step
           "3dface" lp lp1 lp4 rp ""               ; draw the riser
           "3dface" lp3 lp4 "i" rp "" ""           ; draw the right side face
           "3dface" lp2 lp1 "i" lp "" ""           ; draw the left side face
           "3dface" "i" trp "i" rp "i" lp3 tr1 ""  ; draw the thickness
           "3dface" "i" tlp "i" lp "i" lp2 tl1 ""
           "3dface" "i" trp tlp "i" tl1 tr1 "")    ; draw the bottom face
  (command "layer" "m" "scolumn" ""               ; set handrail column layer
           "layer" "c" "cyan" "" ""               ; and color
           "layer" "m" "shandrail" ""             ; set handrail layer and
           "layer" "c" "red" "" "")               ; and color
  (if (or (= ans "L") (= ans "B")) 
    (progn   
      (command "layer" "s" "scolumn" "")
      (command "circle" lh1 (/ step 18))          ; draw the handrail column
      (setq cir (entlast))
      (command "line" lh1 lh2 "")
      (setq lc (entlast))
      (command "tabsurf" (list cir lh1) (list lc lh1))
      (setq tcl (entlast))
      (command "layer" "s" "shandrail" "")
      (command "circle" sh1 (/ step 15)           ; draw the handrail
               "ucs" "y" 90) 
      (setq c1 (entlast)) (setq sh1r (trans sh1 0 1))
      (command "rotate" c1 "" sh1r (rtd (- b))
               "ucs" "")
      (command "line" sh1 sh2 "")
      (setq l1 (entlast))
      (command "tabsurf" (list c1 sh1) (list l1 sh1))
      (setq thl (entlast))
    )
  )         
  (if (or (= ans "R")(= ans "B")) 
    (progn                                        ; draw the right handrail 
      (setq dis (- wide (* 2 (/ wide 15)))         
            sr1 (polar sh1 ac dis)
            sr2 (polar sh2 diag dis)
            rh1 (polar lh1 (+ ac (/ ang 2)) dis)      
            rh2 (polar lh2 (+ ac (/ ang 2)) dis )    
      )
      (command "layer" "s" "scolumn" "")
      (command "circle" rh1 (/ step 18))              
      (setq cir1 (entlast))
      (command "line" rh1 rh2 "")
      (setq rc (entlast))
      (command "tabsurf" (list cir1 rh1) (list rc rh1))
      (setq tcr (entlast))
      (command "layer" "s" "shandrail" "")
      (command "circle" sr1 (/ step 15)
               "ucs" "y" 90) 
      (setq c2 (entlast)) (setq sr1r (trans sr1 0 1))
      (command "rotate" c2 "" sr1r (rtd (- b)) "ucs" ""
               "circle" sr2 (/ step 15) 
               "ucs" "y" 90)
      (setq c3 (entlast)) (setq sr2r (trans sr2 0 1))
      (command "rotate" c3 "" sr2r (rtd (- b)) 
               "ucs" "")
      (command "line" sr1 rh2 "") (setq l2 (entlast))
      (command "line" rh2 sr2 "") (setq l3 (entlast))
      (command "tabsurf" (list c2 sr1) (list l2 sr1)
               "tabsurf" (list c3 sr2) (list l3 sr2))
      (setq thr (entlast))))
  (if (= ans "L")
    (command "block" blk lp "c" tlp lp4 tr1 tcl thl "" "oops"))         
  (if (= ans "R")
    (command "block" blk lp "c" tlp lp4 tr1 tcr thr "" "oops"))
  (if (= ans "B")
    (command "block" blk lp "c" tlp lp4 tr1 tcl tcr thl thr "" "oops"))
  (if (= ans "N")
    (command "block" blk lp "c" tlp lp4 tr1 "" "oops"))
  (setvar "clayer" cla)
  (setq count (1+ count)                       ; initialize counters for loop
        lp (list (car (polar cp diag r))
                 (cadr (polar cp diag r))
                 riser
           )
        riser (+ riser el)
        diag (+ ang ang ac)
  )       
)          ; end SPCALC

(defun sbuild ()                                     
  (command "INSERT" blk lp "" "" (rtd ang))
  (setq  lp (list (car (polar cp diag r))
                  (cadr (polar cp diag r))
                  riser)
         count (1+ count)                       ; increment all counters
         ang (+ ang al)
         diag (+ diag al)
         riser (+ riser el) 
  )         
  (if (< count case)                            ; get last set of coordinates
    (progn                                      ; to form ending face
      (setq lp2 (list (car (polar cp diag r)) 
                      (cadr (polar cp diag r)) 
                      riser)
            lp3 (list (car (polar cp diag (+ r wide)))
                      (cadr (polar cp diag (+ r wide)))
                      riser)
            tl1 (list (car lp2) (cadr lp2) 
                      (- (caddr lp2) (/ thi b))) 
            tr1 (list (car lp3) (cadr lp3) (- (caddr lp3) (/ thi b))) 
      )
    )
  )
)          ; end SBUILD

(defun C:Sp (/ bli cmd cla blksp cp lp riser step wide count hrl blk thi
               lp1 lp2 lp3 lp4 case el rp diag al ang a tr1 tl1)
  (setq bli (getvar "blipmode")
        cmd (getvar "cmdecho")
        cla (getvar "clayer")
  )
  (setvar "blipmode" 0)
  (setvar "cmdecho" 0)
  (spinfo)
  (spcalc)
  (while (< count case)
         (sbuild)
  )
  (command "layer" "s" "spiral" ""                      ; draw ending face
           "3dface" "i" lp3 tr1 "i" tl1 "i" lp2 "")
  (setvar "cecolor" "bylayer")
  (setvar "blipmode" bli)
  (setvar "cmdecho" cmd)
  (setvar "clayer" cla)
  (if (not (equal blksp nil))
      (close blksp)
  )
  (setq blksp
        (open "blksp.lst" "w")
  )
  (write-line blk blksp)
  (close blksp)
  (princ)
)            ; end SP.LSP

